﻿#ifndef ELK_BROWSER_CLIENT_H
#define ELK_BROWSER_CLIENT_H

#include "elk_web_view.h"
#include "include/cef_client.h"

class ElkBrowserClient : public CefClient,
        public CefAudioHandler,
        public CefContextMenuHandler,
        public CefDisplayHandler,
        public CefDownloadHandler,
        public CefFocusHandler,
        public CefLifeSpanHandler,
        public CefLoadHandler,
        public CefRequestHandler
{
public:
    ElkBrowserClient(ElkWebDelegate *delegate,
                     WId parent, const QString &title);
    ElkBrowserClient(ElkWebDelegate *delegate,
                     WId parent, int x, int y, int width, int height);
    ~ElkBrowserClient();

    void SetFocus(bool focus);
    void SetPosition(int x, int y, int width, int height);

    void Load(const QString &url);
    void StopLoad();

    void Reload();
    void ReloadIgnoreCache();

    void GoBack();
    bool CanGoBack() const;

    void GoForward();
    bool CanGoForward() const;

private:
    // CefClient methods:
    virtual CefRefPtr<CefAudioHandler> GetAudioHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefDownloadHandler> GetDownloadHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefFocusHandler> GetFocusHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE {
        return this;
    }
    virtual CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE {
        return this;
    }
    virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
                                          CefRefPtr<CefFrame> frame,
                                          CefProcessId source_process,
                                          CefRefPtr<CefProcessMessage> message) OVERRIDE;

    // CefAudioHandler methods:
    virtual void OnAudioStreamStarted(CefRefPtr<CefBrowser> browser,
                                      const CefAudioParameters &params,
                                      int channels) OVERRIDE;
    virtual void OnAudioStreamPacket(CefRefPtr<CefBrowser> browser,
                                     const float **data,
                                     int frames,
                                     int64 pts) OVERRIDE;
    virtual void OnAudioStreamStopped(CefRefPtr<CefBrowser> browser) OVERRIDE;
    virtual void OnAudioStreamError(CefRefPtr<CefBrowser> browser,
                                    const CefString &message) OVERRIDE;

    // CefContextMenuHandler methods:
    virtual void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
                                     CefRefPtr<CefFrame> frame,
                                     CefRefPtr<CefContextMenuParams> params,
                                     CefRefPtr<CefMenuModel> model) OVERRIDE;
    virtual bool OnContextMenuCommand(CefRefPtr<CefBrowser> browser,
                                      CefRefPtr<CefFrame> frame,
                                      CefRefPtr<CefContextMenuParams> params,
                                      int command_id,
                                      EventFlags event_flags) OVERRIDE;

    // CefDisplayHandler methods:
    virtual void OnAddressChange(CefRefPtr<CefBrowser> browser,
                                 CefRefPtr<CefFrame> frame,
                                 const CefString &url) OVERRIDE;
    virtual void OnTitleChange(CefRefPtr<CefBrowser> browser,
                               const CefString &title) OVERRIDE;
    virtual void OnFullscreenModeChange(CefRefPtr<CefBrowser> browser,
                                        bool fullscreen) OVERRIDE;
    virtual void OnLoadingProgressChange(CefRefPtr<CefBrowser> browser,
                                         double progress) OVERRIDE;
    virtual void OnStatusMessage(CefRefPtr<CefBrowser> browser,
                                 const CefString &value) OVERRIDE;
    virtual bool OnConsoleMessage(CefRefPtr<CefBrowser> browser,
                                  cef_log_severity_t level,
                                  const CefString &message,
                                  const CefString &source,
                                  int line) OVERRIDE;

    // CefDownloadHandler methods:
    virtual void OnBeforeDownload(CefRefPtr<CefBrowser> browser,
                                  CefRefPtr<CefDownloadItem> download_item,
                                  const CefString &suggested_name,
                                  CefRefPtr<CefBeforeDownloadCallback> callback) OVERRIDE;
    virtual void OnDownloadUpdated(CefRefPtr<CefBrowser> browser,
                                   CefRefPtr<CefDownloadItem> download_item,
                                   CefRefPtr<CefDownloadItemCallback> callback) OVERRIDE;

    // CefFocusHandler methods:
    virtual void OnGotFocus(CefRefPtr<CefBrowser> browser) OVERRIDE;
    virtual void OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) OVERRIDE;
    virtual bool OnSetFocus(CefRefPtr<CefBrowser> browser, FocusSource source) OVERRIDE;

    // CefLifeSpanHandler methods:
    virtual bool OnBeforePopup(CefRefPtr<CefBrowser> browser,
                               CefRefPtr<CefFrame> frame,
                               const CefString &target_url,
                               const CefString &target_frame_name,
                               CefLifeSpanHandler::WindowOpenDisposition target_disposition,
                               bool user_gesture,
                               const CefPopupFeatures &popupFeatures,
                               CefWindowInfo &windowInfo,
                               CefRefPtr<CefClient> &client,
                               CefBrowserSettings &settings,
                               CefRefPtr<CefDictionaryValue> &extra_info,
                               bool *no_javascript_access) OVERRIDE;
    virtual void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
    virtual void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;

    // CefLoadHandler methods:
    virtual void OnLoadStart(CefRefPtr<CefBrowser> browser,
                             CefRefPtr<CefFrame> frame,
                             CefLoadHandler::TransitionType transition_type) OVERRIDE;
    virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
                           CefRefPtr<CefFrame> frame,
                           int httpStatusCode) OVERRIDE;

    // CefRequestHandler methods:
    virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                CefRefPtr<CefRequest> request,
                                bool user_gesture,
                                bool is_redirect) OVERRIDE;
    virtual CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(CefRefPtr<CefBrowser> browser,
                                                                           CefRefPtr<CefFrame> frame,
                                                                           CefRefPtr<CefRequest> request,
                                                                           bool is_navigation,
                                                                           bool is_download,
                                                                           const CefString &request_initiator,
                                                                           bool &disable_default_handling) OVERRIDE;

private:
    CefRefPtr<CefBrowser> browser_;
    ElkWebDelegate *delegate_ = nullptr;
    IMPLEMENT_REFCOUNTING(ElkBrowserClient);
};

#endif  // ELK_BROWSER_CLIENT_H
